﻿using NPOI.SS.UserModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UIWindows.Domains;
using UIWindows.Enums;
using UIWindows.GlobalStatics;
using UIWindows.Models;
using XingLucifer.IBase.Enums;
using Kinlo.Entitys;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
using System.ComponentModel;
using NPOI.SS.Formula.Functions;
using System.Reflection;
using Newtonsoft.Json.Linq;
using NewLife.Data;
using System.Windows.Threading;

namespace UIWindows.Tools.Helper
{
    public class ExportHelper
    {
        public static bool Export_ProductionData_xls(string path, MachineInfoTypes MachineInfoValue,XCode.Expression expression, ObservableCollection<DisplayItemsModel> displayItems)
        {
			try
			{
                var datas = QuiryEntity(MachineInfoValue, expression);
                //IList<ProductionData> datas = ProductionData.FindAll(expression);
                NPOI.HSSF.UserModel.HSSFWorkbook book = new NPOI.HSSF.UserModel.HSSFWorkbook();
                ISheet sheet = book.CreateSheet("Sheet1");//获取第一个工作薄
                int rowCount = 0;
                int countSender = 0;
                IRow row = sheet.CreateRow(rowCount);
                var plist = displayItems.Where(x => x.IsOutput);
                int length = plist.Count();
                for (int i = 0; i < length; i++) row.CreateCell(i, CellType.String);
                foreach (var sender in plist.Select(x => x.Description))
                {
                    row.Cells[countSender].SetCellValue(sender);
                    countSender += 1;
                }
                rowCount += 1;
                foreach (var item in datas)
                {
                    row = sheet.CreateRow(rowCount);
                    for (int i = 0; i < length; i++) 
                        row.CreateCell(i, CellType.String);
                    countSender = 0;
                    foreach (var item1 in plist)
                    {
                        try
                        {
                            switch (item1.DataType)
                            {                               
                                case "无类型":
                                    //row.Cells[countSender].SetCellValue($"{item[item1.Name]}");
                                    break;
                                case "浮点型":
                                    //row.Cells[countSender].SetCellValue($"{item[item1.Name]:F2}");
                                    //row.Cells[countSender].SetCellValue($"{item[item1.Name]}");
                                    break;
                                //case "时间型":
                                //    long lvalue = (long)item[item1.Name];
                                //    if (lvalue > 0)
                                //    {
                                //        row.Cells[countSender].SetCellValue($"{lvalue.GetDateTime():yyyy-MM-dd HH:mm:ss}");
                                //    }
                                //    else
                                //    {
                                //        row.Cells[countSender].SetCellValue("0000-00-00 00:00:00");
                                //    }
                                //    break;
                                case "时间型":
                                    //object rawValue = item[item1.Name];
  
                                    //long lvalue = rawValue != null ? Convert.ToInt64(rawValue) : 0;

                                    //if (lvalue > 0)
                                    //{
                                    //    row.Cells[countSender].SetCellValue($"{lvalue.GetDateTime():yyyy-MM-dd HH:mm:ss}");
                                    //}
                                    //else
                                    //{

                                    //    row.Cells[countSender].SetCellValue("0001-01-01 00:00:00");
                                    //}
                                    break;
                                default:
                                    //row.Cells[countSender].SetCellValue($"{item[item1.Name]}");
                                    break;
                            }
                           
                        }
                        catch (Exception ex)
                        {
                            //row.Cells[countSender].SetCellValue($"{item[item1.Name]}");
                            $"数据导出异常：{ex.Message}".RunLog(MessageLevelType.错误);
                        }finally
                        {                            
                            countSender += 1;
                        }
                    }
                    rowCount += 1;
                }
                //导出excel
                if (!Directory.Exists(Path.GetDirectoryName(path))) { Directory.CreateDirectory(Path.GetDirectoryName(path)); }
                using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
                {
                    book.Write(fs);
                }

                book.Close();
                return true;
            }
			catch (Exception ex)
			{
                $"数据导出异常：{ex}".RunLog(MessageLevelType.错误);
			}
            return false;
        }
        public static bool Export_ProductionData_xlsx(string path, MachineInfoTypes MachineInfoValue, XCode.Expression expression, ObservableCollection<DisplayItemsModel> displayItems)
        {
            try
            {
                //MachineInfoTypes MachineInfoValue = MachineInfoTypes.预充装盘;
                //IList<object> datas
                //IList<Plate> datas = Plate.FindAll(expression);
                IList<object> datas = QuiryEntity(MachineInfoValue, expression);

                //window.Dispatcher.Invoke(() => {
                //    datas 
                //});
                //NPOI.HSSF.UserModel.HSSFWorkbook book = new NPOI.HSSF.UserModel.HSSFWorkbook();
                //ISheet sheet = book.CreateSheet("Sheet1");//获取第一个工作薄
                IWorkbook book = new XSSFWorkbook(); // 使用 XSSFWorkbook 代替 xlsx 格式
                ISheet sheet = book.CreateSheet("Sheet1");
                int rowCount = 0;
                int countSender = 0;
                IRow row = sheet.CreateRow(rowCount);
                var plist = displayItems.Where(x => x.IsOutput);
                int length = plist.Count();
                for (int i = 0; i < length; i++) row.CreateCell(i, CellType.String);
                //Thread.Sleep(200);
                foreach (var sender in plist.Select(x => x.Description))
                {
                    row.Cells[countSender].SetCellValue(sender);
                    countSender += 1;
                }

                rowCount += 1;
                foreach (var item in datas)
                {
                    row = sheet.CreateRow(rowCount);
                    for (int i = 0; i < length; i++)
                        row.CreateCell(i, CellType.String);
                    countSender = 0;
                    foreach (var item1 in plist)
                    {
                        try
                        {
                            var propValue = item.GetType().GetProperty(item1.Name).GetValue(item, null);
                            switch (item1.DataType)
                            {
                                case "无类型":

                                    row.Cells[countSender].SetCellValue($"{propValue}");
                                    break;
                                case "浮点型":
                                    row.Cells[countSender].SetCellValue($"{propValue}");
                                    break;
                                case "时间型":
                                    row.Cells[countSender].SetCellValue($"{propValue}");
                                    //object rawValue = item[item1.Name];

                                    //long lvalue = rawValue != null ? Convert.ToInt64(rawValue) : 0;

                                    //if (lvalue > 0)
                                    //{
                                    //    row.Cells[countSender].SetCellValue($"{lvalue.GetDateTime():yyyy-MM-dd HH:mm:ss}");
                                    //}
                                    //else
                                    //{

                                    //    row.Cells[countSender].SetCellValue("0001-01-01 00:00:00");
                                    //}
                                    break;
                                default:
                                    row.Cells[countSender].SetCellValue($"{propValue}");
                                    break;
                            }

                        }
                        catch (Exception ex)
                        {
                            //row.Cells[countSender].SetCellValue($"{item[item1.Name]}");
                            $"数据导出异常：{ex.Message}".RunLog(MessageLevelType.错误);
                        }
                        finally
                        {
                            countSender += 1;
                        }
                    }
                    rowCount += 1;
                }
                //导出excel
                if (!Directory.Exists(Path.GetDirectoryName(path))) { Directory.CreateDirectory(Path.GetDirectoryName(path)); }
                using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
                {
                    book.Write(fs, true);
                }

                book.Close();


                return true;
            }
            catch (Exception ex)
            {
                $"数据导出异常：{ex}".RunLog(MessageLevelType.错误);
            }
            return false;
        }


        private static IList<object> QuiryEntity(MachineInfoTypes MachineInfoValue, XCode.Expression expression, PageParameter page=null)
        {

            IList<object> list = null;
            switch (MachineInfoValue)
            {
                case MachineInfoTypes.卷芯上料:
                    list = CoilCoreLoadingData.FindAll(expression, page).Cast<object>().ToList();
                    break;
                case MachineInfoTypes.换套杯:
                    list = CupSleeveChangingData.FindAll(expression, page).Cast<object>().ToList();
                    break;
                case MachineInfoTypes.折极耳:
                    list = PoleEarFoldingData.FindAll(expression, page).Cast<object>().ToList();
                    break;
                case MachineInfoTypes.入壳机:
                    list = ShellInsertionData.FindAll(expression, page).Cast<object>().ToList();
                    break;
                case MachineInfoTypes.点底焊:
                    list = SpotoWeldData.FindAll(expression, page).Cast<object>().ToList();
                    break;
                case MachineInfoTypes.辊槽机:
                    list = GrooveRollingMachineData.FindAll(expression, page).Cast<object>().ToList();
                    break;
                case MachineInfoTypes.短路测试仪:
                    list = ShortCircuitTesterData.FindAll(expression, page).Cast<object>().ToList();
                    break;
                case MachineInfoTypes.装盘机:
                    list = TrayFillerData.FindAll(expression, page).Cast<object>().ToList();
                    break;
                case MachineInfoTypes.拆盘机:
                    list = DismantlingDiscData.FindAll(expression, page).Cast<object>().ToList();
                    break;
                case MachineInfoTypes.盖帽焊:
                    list = CapWeldingData.FindAll(expression, page).Cast<object>().ToList();
                    break;
                case MachineInfoTypes.封口机:
                    list = SealingMachineData.FindAll(expression, page).Cast<object>().ToList();
                    break;
                case MachineInfoTypes.清洗机:
                    list = CleaningData.FindAll(expression, page).Cast<object>().ToList();
                    break;
                case MachineInfoTypes.套膜机:
                    list = MantleData.FindAll(expression, page).Cast<object>().ToList();
                    break;
                case MachineInfoTypes.喷码机:
                    list = MarkingData.FindAll(expression, page).Cast<object>().ToList();
                    break;
                case MachineInfoTypes.预充装盘:
                    list = Plate.FindAll(expression, page).Cast<object>().ToList();
                    break;
                default: break;
            }
            return list;
        }

        public static bool Export_ProductionData_CSV(string path, XCode.Expression expression, ObservableCollection<DisplayItemsModel> displayItems)
        {
            try
            {
                IList<ProductionData> datas = ProductionData.FindAll(expression);

                using (StreamWriter sw = new StreamWriter(path, false, Encoding.UTF8))
                {
                    var plist = displayItems.Where(x => x.IsOutput).ToList();
                    int length = plist.Count();

                    // 写入表头
                    sw.WriteLine(string.Join(",", plist.Select(x => x.Description)));

                    // 写入数据
                    foreach (var item in datas)
                    {
                        var rowValues = new List<object>();

                        foreach (var item1 in plist)
                        {
                            try
                            {
                                if (item1.Description.Contains("测漏真空"))
                                {
                                    rowValues.Add($"{item[item1.Name]:F3}");
                                }
                                else
                                {
                                    switch (item1.DataType)
                                    {
                                        //case "无类型":
                                        case "浮点型":
                                            rowValues.Add($"{item[item1.Name]}");
                                            break;
                                        case "时间型":
                                            object rawValue = item[item1.Name];
                                            long lvalue = rawValue != null ? Convert.ToInt64(rawValue) : 0;

                                            if (lvalue > 0)
                                            {
                                                rowValues.Add($"{lvalue.GetDateTime():yyyy-MM-dd HH:mm:ss}");
                                            }
                                            else
                                            {

                                                rowValues.Add("0001-01-01 00:00:00");
                                            }
                                            break;
                                        default:
                                            rowValues.Add($"{item[item1.Name]}");
                                            //rowValues.Add($"\"{item[item1.Name]}\"");
                                            break;
                                    }
                                }

                            }
                            catch (Exception ex)
                            {
                                rowValues.Add($"{item[item1.Name]}");
                                $"数据导出异常：{ex.Message}".RunLog(MessageLevelType.错误);
                            }
                        }

                        // 将一行数据写入CSV
                        sw.WriteLine(string.Join(",", rowValues));
                    }
                }

                $"数据已导出至：{path}".RunLog(MessageLevelType.成功);
                return true;
            }
            catch (Exception ex)
            {
                $"数据导出异常：{ex}".RunLog(MessageLevelType.错误);
                return false;
            }
        }

      

        /// <summary>
        /// 导入
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static IEnumerable<T> ImproExcel<T>(string filePath) where T : new()
        {
            List<T> datas = new List<T>();
            IWorkbook workbook = null;
            try
            {
                using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                {
                    if (Path.GetExtension(filePath).ToLower() == ".xlsx") // 2007版本
                        workbook = new XSSFWorkbook(fs);
                    else if (Path.GetExtension(filePath).ToLower() == ".xls") // 2003版本
                        workbook = new HSSFWorkbook(fs);
                    ISheet sheet = workbook.GetSheetAt(0);
                    IRow HeaderRow = sheet.GetRow(0);

                    //  T data = Activator.CreateInstance<T>();
                    for (int i = 1; i < sheet.LastRowNum + 1; i++)
                    {
                        T t = new T();
                        for (int r = 0; r < HeaderRow.LastCellNum; r++)
                        {
                            foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(t.GetType()))
                            {
                                var batAtt = property.Attributes.OfType<DescriptionAttribute>().FirstOrDefault();
                                if (batAtt != null)
                                {
                                    if (HeaderRow.GetCell(r).StringCellValue == batAtt.Description)
                                    {
                                        string val = string.Empty;
                                        var cell = sheet.GetRow(i).GetCell(r);
                                        if (cell != null)
                                        {
                                            switch (cell.CellType)
                                            {
                                                case CellType.Blank:
                                                    val = "";
                                                    break;
                                                case CellType.Numeric:
                                                    short format = cell.CellStyle.DataFormat;
                                                    //对时间格式（2015.12.5、2015/12/5、2015-12-5等）的处理 
                                                    if (format == 14 || format == 31 || format == 57 || format == 58)
                                                        val = cell.DateCellValue.ToString();
                                                    else
                                                        val = cell.NumericCellValue.ToString();
                                                    if (cell.CellStyle.DataFormat == 177 || cell.CellStyle.DataFormat == 178 || cell.CellStyle.DataFormat == 188)
                                                        val = cell.NumericCellValue.ToString("#0.00");
                                                    break;
                                                case CellType.String:
                                                    val = cell.StringCellValue;
                                                    break;
                                                case CellType.Formula:
                                                    try
                                                    {
                                                        val = cell.NumericCellValue.ToString();
                                                        if (cell.CellStyle.DataFormat == 177 || cell.CellStyle.DataFormat == 178 || cell.CellStyle.DataFormat == 188)
                                                            val = cell.NumericCellValue.ToString("#0.00");
                                                    }
                                                    catch
                                                    {
                                                        try
                                                        {
                                                            val = cell.StringCellValue;
                                                        }
                                                        catch { }
                                                    }
                                                    break;
                                                case CellType.Error:
                                                    break;
                                                default:
                                                    val = cell.StringCellValue;
                                                    break;
                                            }
                                        }
                                        var dataType = property.PropertyType;
                                        if (dataType == typeof(int) || dataType.BaseType == typeof(Enum))
                                        {
                                            property.SetValue(t, int.TryParse(val, out int v) ? v : 0);
                                        }
                                        else if (dataType == typeof(double))
                                        {

                                            property.SetValue(t, double.TryParse(val, out double v) ? v : 0d);
                                        }
                                        else if (dataType == typeof(float))
                                        {

                                            property.SetValue(t, float.TryParse(val, out float v) ? v : 0f);
                                        }
                                        else if (dataType == typeof(UInt16))
                                        {

                                            property.SetValue(t, UInt16.TryParse(val, out UInt16 v) ? v : (UInt16)0);
                                        }
                                        else if (dataType == typeof(bool))
                                        {
                                            if (bool.TryParse(val, out bool v))
                                                property.SetValue(t, v);
                                            else
                                            {
                                                if (val == "1" || val.ToLower() == "true")
                                                    property.SetValue(t, true);
                                                else
                                                    property.SetValue(t, false);
                                            }
                                        }
                                        else if (dataType == typeof(DateTime))
                                        {
                                            property.SetValue(t, DateTime.TryParse(val, out DateTime v) ? v : DateTime.Now);
                                        }                                       
                                        else
                                        {
                                            property.SetValue(t, val);
                                        }
                                        break;
                                    }
                                }
                            }

                           
                        }
                        datas.Add(t);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex); 
            }
            return datas;
        }


        /// <summary>
        /// 导入
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="path"></param>
        /// <returns></returns>
        public static IEnumerable<T> ImportData<T>(string path)
        {
            try
            {
                List<T> dataList = new List<T>();

                using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
                {
                    HSSFWorkbook book = new HSSFWorkbook(fs);
                    ISheet sheet = book.GetSheetAt(0);

                    if (sheet != null)
                    {
                        IRow headerRow = sheet.GetRow(0);
                        Dictionary<int, string> columnHeaders = new Dictionary<int, string>();
                        for (int i = 0; i < headerRow.LastCellNum; i++)
                        {
                            ICell headerCell = headerRow.GetCell(i);
                            columnHeaders[i] = headerCell.StringCellValue;
                        }

                        for (int rowIdx = 1; rowIdx <= sheet.LastRowNum; rowIdx++)
                        {
                            IRow dataRow = sheet.GetRow(rowIdx);
                            if (dataRow != null)
                            {
                                T dataItem = Activator.CreateInstance<T>();

                                foreach (var colIdx in columnHeaders.Keys)
                                {
                                    ICell dataCell = dataRow.GetCell(colIdx);
                                    string columnName = columnHeaders[colIdx];

                                    PropertyInfo property = typeof(T).GetProperty(columnName);
                                    if (property != null && dataCell != null)
                                    {
                                        object cellValue = dataCell.ToString();
                                        Type propertyType = property.PropertyType;
                                        if(propertyType.Name.Contains("Int"))
                                        {
                                            property.SetValue(dataItem,int.Parse(cellValue.ToString()));
                                        }else if (propertyType.Name.Contains("Bool"))
                                        {
                                            property.SetValue(dataItem, Convert.ToBoolean(cellValue));
                                        }
                                        else
                                        {
                                            property.SetValue(dataItem, cellValue);
                                        }
                                       
                                    }
                                }

                                dataList.Add(dataItem);
                            }
                        }
                    }
                }

                return dataList;
            }
            catch (Exception ex)
            {
                Console.WriteLine("导入数据失败：" + ex.Message);
                return null;
            }
        }
        /// <summary>
        /// 导出
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="path"></param>
        /// <param name="ts"></param>
        /// <returns></returns>
        public static bool Export_Data<T>(string path, IEnumerable<T> ts)
        {
            try
            {
                // 创建工作簿和工作表
                NPOI.HSSF.UserModel.HSSFWorkbook book = new NPOI.HSSF.UserModel.HSSFWorkbook();
                ISheet sheet = book.CreateSheet("Sheet1");

                // 设置列标题（假设 T 是一个具有公共属性的类）
                IRow headerRow = sheet.CreateRow(0);
                PropertyInfo[] properties = typeof(T).GetProperties();
                for (int i = 0; i < properties.Length; i++)
                {
                    ICell headerCell = headerRow.CreateCell(i);
                    headerCell.SetCellValue(properties[i].Name);
                }

                // 填充数据
                int rowCount = 1;
                foreach (var item in ts)
                {
                    IRow dataRow = sheet.CreateRow(rowCount);
                    for (int i = 0; i < properties.Length; i++)
                    {
                        ICell dataCell = dataRow.CreateCell(i);
                        object value = properties[i].GetValue(item);
                        dataCell.SetCellValue(value != null ? value.ToString() : "");
                    }
                    rowCount++;
                }

                // 保存文件
                using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
                {
                    book.Write(fs);
                    fs.Close();
                }

                return true;
            }
            catch (Exception ex)
            {
                // 处理异常，这里简单地输出异常信息，你可以根据实际情况进行处理
                Console.WriteLine("导出数据失败：" + ex.Message);
                return false;
            }
        }

    }

   
}
